//
//$Id: re.h 687 2011-03-13 12:21:29Z Andrew.Tsyganov $
#pragma once

#include "types.h"
#include <stack>

const std::string kREXmlNode             = "re";
const std::string kREXmlNameAttr         = "name";
const std::string kREXmlSymbolsNumAttr   = "symbols_num";

const std::string kREXmlEpsilonNode      = "epsilon";

const std::string kREXmlExpressionNode   = "expression";

const std::string kREXmlSymbolsNode      = "symbols";
const std::string kREXmlSymbolNode       = "symbol";

const std::string kREXmlIDAttr           = "id";

const std::string kREDefaultEpsilonName  = "epsilon"; 

class RE
{
private:
    std::string name_;
    u_t symbols_num_;

	Label epsilon_;
	std::vector<Label> symbols_;

	std::string      infix_;
	std::vector<u_t> postfix_;

	int  priority(std::string s) const;
    bool operand(std::string s) const;
	u_t  code(std::string s) const;
	bool parse();
public:
    // constructors
	RE();
	RE(std::string const& name, u_t const symbols_num, std::string const& infix = "", std::string const& epsilon = kREDefaultEpsilonName); 
	RE(std::string const& file);
	RE(RE const& re);
    
	// init and clear
	bool init(std::string const& name, u_t const symbols_num, std::string const& infix = "", std::string const& epsilon = kREDefaultEpsilonName);
	void clear();

	// name routines
	inline std::string get_Name() const { return name_; }
	inline void set_Name(std::string name) { name_ = name; }

	// epsilon routines
	inline std::string get_Epsilon() const { return epsilon_; }
	inline void set_Epsilon(std::string const& epsilon) { epsilon_ = epsilon; }

	// symbols routines
	inline u_t get_Symbols_Num() const { return symbols_num_; }
	u_t get_Symbol_ID(Label const& sym) const;
	inline std::vector<Label> const& get_Symbols() const { return symbols_; }
	
	void set_Symbols(std::vector<Label> const& vl);
	inline void reset_Symbols() { symbols_.clear(); }
	
	std::string symbol_To_String(u_t const id, std::string const& pfx = "", Labels_Type const lt = TXT) const;

	// infix and postfix routines
	std::string const& get_Infix() const { return infix_; }
	std::vector<u_t> const& get_Postfix() const { return postfix_; }

	// printing routines
	void print_TXT(std::ostream& os) const;

	// saving and loading routines
    bool load_XML(std::string const& file);

	// miscellaneous routines
	std::string lexeme(u_t code) const;
	bool operand(u_t code) const;
};

//EOF!

